package com.copractice.data.entity;

import java.io.Serializable;

import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.apache.commons.lang.builder.ToStringBuilder;

/**
 * Implementation of <code>Persistable</code> interface for entities with identity of type Long
 *
 * Next rules should be used while adding new entity:
 * <ul>
 * <li>Any entity that has identity of type Long SHOULD extend this class</li>
 * <li>Entity that has identity other than Long SHOULD directly implement <code>Persistable</code> interface</li>
 * </ul>
 *
 * @author Dmitry Churbanov (dmitry.churbanov@gmail.com)
 * @version 1.0 03/13/2009
 */
@SuppressWarnings("serial")
public class PersistentObject implements Persistable<Long>, Serializable {

    /* Entity identity */
    private Long id;

    /**
     * Default constructor. Constructs new <code>PersistentObject</code> object
     * that represents new entity without specified identity.
     */
    public PersistentObject() {
    }

    /**
     * Constructs new <code>PersistentObject</code> object that represents new
     * entity with the specified <code>id</code> identity.
     *
     * @param id entity identity
     */
    public PersistentObject(Long id) {
        this.id = id;
    }

    /**
     * 
     * @return entity identity
     * @see Persistable#getId() 
     */
    public Long getId() {
        return id;
    }

    /**
     * Sets entity identity.
     * 
     * @param id  entity identity
     */
    public void setId(Long id) {
        this.id = id;
    }

    /**
     * Compares this object to the specified object. This method represents equivalence
     * of records in the database.
     * </p>
     * Entities with composite identifier SHOULD override this method to keep right
     * behavior. 
     *
     * @param obj  the object to compare with.
     * @return  <code>true</code> if the objects are the same;
     *          <code>false</code> otherwise.
     */
    @Override
    public boolean equals(Object obj) {
       if (!(obj instanceof PersistentObject)) {
         return false;
       }
       if (this == obj) {
         return true;
       }
       PersistentObject rhs = (PersistentObject) obj;
       return new EqualsBuilder()
                  .append(getId(), rhs.getId())
                  .isEquals();
    }

    /**
     * Returns a hash code for this <code>PersistentObject</code>.
     *
     * @return a hash code value for this object.
     */
    @Override
    public int hashCode() {
        return new HashCodeBuilder(17, 31)
                   .append(getId())
                   .toHashCode();
    }

    /**
     * Returns a string representation of the entity.
     * 
     * @return a string representation of the entity.
     */
    @Override
    public String toString() {
        return new ToStringBuilder(this)
                   .append("id", getId())
                   .toString();
    }
    
}
